package xmu.ackerman.utils;

import com.sun.javafx.scene.shape.PathUtils;
import xmu.ackerman.MyHttpController;
import xmu.ackerman.http.handler.HtmlHandler;

import javax.swing.text.Style;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * @Author: Ackerman
 * @Description: 获取同一路径下的所有类 以及 实现类
 * @Date: Created in 下午8:21 18-3-15
 */
public class ClassUtil {

    /**
    * @Description: 获取C的子类或者实现类
    * @Date: 下午8:44 18-3-15
    */
    public static Set<Class<?>> getAllAssignClasses(Class<?> C)
            throws IOException, ClassNotFoundException{

        Set<Class<?>> classSet = new HashSet<Class<?>>();
        for(Class<?> c : getClasses(C)){
            if(C.isAssignableFrom(c) && !C.equals(c)){
                classSet.add(c);
            }
        }

        return classSet;
    }

    /**
    * @Description: 获取当前路径下的所有类
    * @Date: 下午8:36 18-3-15
    */
//    public static Set<Class<?>> getClasses(Class<?> C) throws
//            IOException, ClassNotFoundException{
//
//        String x = System.getProperty("java.class.path");
//        int firstIndex = x.lastIndexOf(System.getProperty("path.separator"))+1;
//        int lastIndex = x.lastIndexOf(File.separator) +1;
//        System.out.println("x1=" + x);
//        x = x.substring(firstIndex, lastIndex);
//        System.out.println("x2=" + x);
//
//        String bag = C.getPackage().getName();
//        String path = bag.replace(".", "/");
//        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
//        URL url = classLoader.getResource(path);
//        File file = new File(url.getFile());
//
//        System.out.println("beg===" +url.getPath());
//
//        return getClasses(file, bag);
//    }

    public static Set<Class<?>> getClasses(Class<?> C) {
        Set<Class<?>> x = null;
        try {
            x = getClasssFromJarFile(MyHttpController.JAR_PATH, MyHttpController.AOP_DIR);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return x;
    }


    /**
     * 从jar文件中读取指定目录下面的所有的class文件
     *
     * @param jarPaht
     *            jar文件存放的位置
     * @param filePaht
     *            指定的文件目录
     * @return 所有的的class的对象
     */
    private static Set<Class<?>> getClasssFromJarFile(String jarPaht, String filePaht) {
        Set<Class<?>> clazzs = new HashSet<>();

        JarFile jarFile = null;
        try {
            jarFile = new JarFile(jarPaht);
        } catch (IOException e1) {
            e1.printStackTrace();
        }

        List<JarEntry> jarEntryList = new ArrayList<JarEntry>();

        Enumeration<JarEntry> ee = jarFile.entries();
        while (ee.hasMoreElements()) {
            JarEntry entry = (JarEntry) ee.nextElement();
            // 过滤我们出满足我们需求的东西
            if (entry.getName().startsWith(filePaht) && entry.getName().endsWith(".class")) {
                jarEntryList.add(entry);
            }
        }
        for (JarEntry entry : jarEntryList) {
            String className = entry.getName().replace('/', '.');
            className = className.substring(0, className.length() - 6);

            try {
                clazzs.add(Thread.currentThread().getContextClassLoader().loadClass(className));
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }

        return clazzs;

    }

        /**
        * @Description: 迭代查找类
        * @Date: 下午8:24 18-3-15
        */
    private static Set<Class<?>> getClasses(File dir, String bag) throws ClassNotFoundException{
        Set<Class<?>> classSet = new HashSet<Class<?>>();

        if (dir == null) {
            return classSet;
        }

        for (File f : dir.listFiles()) {
            if (f.isDirectory()) {
                classSet.addAll(getClasses(f, bag + "." + f.getName()));
            }
            String name = f.getName();
            if(name.endsWith(".class")){
                classSet.add(Class.forName(bag+"."+name.substring(0, name.length()-6)));
            }
        }

        return classSet;
    }

    public static void main(String []args){
        try {
            getAllAssignClasses(HtmlHandler.class);

//            String x = System.getProperty("java.class.path");
//            int firstIndex = x.lastIndexOf(System.getProperty("path.separator"))+1;
//            int lastIndex = x.lastIndexOf(File.separator) +1;
//            x = x.substring(firstIndex, lastIndex);
        }catch (Exception e){

        }
    }

}
